package com.example.templateapp.ui.widget

import android.animation.ObjectAnimator
import android.content.Context
import android.graphics.*
import android.util.AttributeSet
import android.util.Log
import android.view.View
import android.view.ViewGroup
import android.view.animation.Animation
import android.view.animation.LinearInterpolator
import com.example.templateapp.R
import kotlin.math.cos
import kotlin.math.sin

class CircleLayout : ViewGroup {

    private var radius: Float = 0f
    private var angleOffset: Int = 0
    private var degreeDelta: Int = 0

    constructor(context: Context) : super(context)


    constructor(context: Context, attrs: AttributeSet, defStyle: Int) : super(
        context,
        attrs,
        defStyle
    )

    constructor(context: Context, attrs: AttributeSet) : super(context, attrs) {
        setWillNotDraw(false)
        val a = context.obtainStyledAttributes(attrs, R.styleable.CircleLayout)

        radius = a.getDimension(R.styleable.CircleLayout_radius, 0f)
        angleOffset = a.getInteger(R.styleable.CircleLayout_offset_angle, 0)
        a.recycle()
        setBackgroundColor(Color.TRANSPARENT)
    }


    private var parentLeft = 0
    private var parentRight = 0
    private var parentTop = 0
    private var parentBottom = 0
    override fun onLayout(changed: Boolean, l: Int, t: Int, r: Int, b: Int) {
        val count = childCount

        degreeDelta = 360 / count

        parentLeft = paddingLeft
        parentRight = r - l - paddingRight

        parentTop = paddingTop
        parentBottom = bottom - top - paddingBottom

        if (radius == 0f) {
            radius = ((parentRight - parentLeft) / 2 - getChildAt(0).measuredWidth).toFloat()
        }

        if (count < 1) return

        for (i in 0 until count) {
            val v = getChildAt(i)
            if (v.visibility == View.GONE) continue
            val width = v.measuredWidth
            val height = v.measuredHeight
            var childLeft = (parentLeft + (parentRight - parentLeft - width) / 2)
            var childTop = parentTop + (parentBottom - parentTop - height) / 2
            Log.d("CircleLayout", "before：i=$i,childL=$childLeft,childT=$childTop")
            if (count > 1) {
                childLeft -=
                    (radius * sin((i * degreeDelta + angleOffset).toDouble() * Math.PI / 180)).toInt()
                childTop -=
                    (radius * cos((i * degreeDelta + angleOffset).toDouble() * Math.PI / 180)).toInt()
            }
            Log.d("CircleLayout", "after：i=$i,childL=$childLeft,childT=$childTop")
            v.layout(childLeft, childTop, childLeft + width, childTop + height)
        }

    }


    override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec)
        val sizeWidth = MeasureSpec.getSize(widthMeasureSpec)
        val sizeHeight = MeasureSpec.getSize(heightMeasureSpec)
        measureChildren(widthMeasureSpec, heightMeasureSpec)
        setMeasuredDimension(sizeWidth, sizeHeight)
    }

    override fun onDraw(canvas: Canvas?) {
        super.onDraw(canvas)
        val paint = Paint(Paint.ANTI_ALIAS_FLAG)
        paint.style = Paint.Style.STROKE
        paint.strokeWidth = 5f
        canvas?.drawPath(circlePath(0, false), paint)

    }

    fun startRotate(duration: Long, childIdx: Int) {
        val child = getChildAt(childIdx)
        val path = circlePath(childIdx)

        ObjectAnimator.ofFloat(child, "x", "y", path).apply {
            setDuration(duration)
            interpolator = LinearInterpolator()
            repeatCount = Animation.INFINITE
            start()
        }
        ObjectAnimator.ofFloat(child, "rotation", 0.5f, 360f).apply {
            setDuration(3000)
            interpolator = LinearInterpolator()
            repeatCount = Animation.INFINITE
            start()
        }
    }

    private fun circlePath(childIdx: Int, isOffset: Boolean = true): Path {
        val path = Path()
        val x = parentLeft + (parentRight - parentLeft) / 2
        val y = parentTop + (parentBottom - parentTop) / 2

        val halfWidth = getChildAt(childIdx).measuredWidth / 2
        val r = radius + halfWidth
        path.addCircle(x.toFloat(), y.toFloat(), r, Path.Direction.CCW)

        val matrix = Matrix()
        matrix.postRotate(-90f - (childIdx * 360f / childCount), x.toFloat(), y.toFloat())
        if (isOffset) {
            matrix.postTranslate(-halfWidth.toFloat(), -halfWidth.toFloat())
        }
        path.transform(matrix)
        return path
    }


}